<template>
  <div ref="mapContainer" style="width: 100vw; height: 100vh;"></div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import * as d3 from 'd3';

const mapContainer = ref(null);
const scene = ref(null);
const camera = ref(null);
const renderer = ref(null);
const projection = ref(null);

const createLightPillar = (coordinates) => {
    console.log("projection.value",projection.value)
  if (!projection.value || typeof projection.value !== 'function') {
    console.error('Projection function is not available');
    return;
  }
  
  coordinates.forEach(([lng, lat]) => {
      const [x, y] = projection.value([lng, lat]);
      const px = x - window.innerWidth / 2;
      const py = -y + window.innerHeight / 2;

    // 创建渐变线条几何体
    const lineLength = 200;
    const lineGeometry = new THREE.BufferGeometry();
    const linePositions = new Float32Array(30 * 3);
    const lineWidths = new Float32Array(30);
    
    // 设置线条顶点位置和宽度
    for (let i = 0; i < 30; i++) {
      const i3 = i * 3;
      linePositions[i3] = 0;
      linePositions[i3 + 1] = -i * (lineLength / 30);
      linePositions[i3 + 2] = 0;
      
      // 头部粗尾部细
      lineWidths[i] = 10 * (1 - i / 30);
    }
    
    lineGeometry.setAttribute('position', new THREE.BufferAttribute(linePositions, 3));
    
    // 创建线条材质
    const lineMaterial = new THREE.LineBasicMaterial({
      color: 0xffffff,
      transparent: true,
      opacity: 0.9,
      linewidth: 5,
      depthTest: false
    });
    
    const line = new THREE.Line(lineGeometry, lineMaterial);
    line.renderOrder = 2;
    line.position.set(px, py, 0);
    scene.value.add(line);

    // 线条下落动画
    const animateLine = () => {
      if (line.position.y > py) {
        line.position.y -= 10;
        requestAnimationFrame(animateLine);
      } else {
        scene.value.remove(line);
        // 砸落后创建波动光圈
        const ringGeometry = new THREE.RingGeometry(10, 50, 32);
        const ringMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide, transparent: true, opacity: 1, depthTest: false });
        const ring = new THREE.Mesh(ringGeometry, ringMaterial);
        ring.renderOrder = 1;
        ring.position.set(px, py, 0);
        scene.value.add(ring);
        animateRing(ring);
      }
    };
    animateLine();
  });
};

const animateRing = (ring) => {
  let scale = 1;
  let opacity = 1;
  
  const animate = () => {
    scale += 0.05;
    opacity -= 0.02;
    
    if (opacity > 0) {
      ring.scale.set(scale, scale, 1);
      ring.material.opacity = opacity;
      requestAnimationFrame(animate);
    } else {
      scene.value.remove(ring);
    }
  };
  animate();
};

onMounted(() => {
    const scene = new THREE.Scene();
    // 调整相机位置，适当增加 z 值，让相机离地图更远一些
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
    camera.position.set(0, 0, 1500); // 调整相机位置
    camera.lookAt(0, 0, 0); // 确保相机看向场景中心

    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    mapContainer.value.appendChild(renderer.domElement);

    const controls = new OrbitControls(camera, renderer.domElement);

    const projection = d3.geoMercator()
      .scale(1000)
      .center([104.0, 36.0]) // 中国中心经纬度
      .translate([window.innerWidth / 2, window.innerHeight / 2]);

      
    const path = d3.geoPath().projection(projection);

    fetch('/static/json/china.geojson')
      .then(response => response.json())
      .then(geojson => {
        const map = new THREE.Object3D();
        
        geojson.features.forEach(feature => {
          if (feature.geometry.type === 'Polygon') {
            const polygonCoords = feature.geometry.coordinates[0];
            const shape = new THREE.Shape();
            
            polygonCoords.forEach(([lng, lat], i) => {
              try {
                const [x, y] = projection([lng, lat]);
                if (typeof x === 'number' && typeof y === 'number' && !isNaN(x) && !isNaN(y)) {
                  const px = x - window.innerWidth / 2;
                  const py = -y + window.innerHeight / 2;
                  
                  if (i === 0) {
                    shape.moveTo(px, py);
                  }
                  shape.lineTo(px, py);
                } else {
                  console.warn(`Invalid coordinates at index ${i}: [${lng}, ${lat}]`);
                }
              } catch (error) {
                console.error(`Error processing coordinates at index ${i}:`, error);
              }
            });
            
            const extrudeSettings = {
              depth: 10, // 设置地图厚度
              bevelEnabled: false
            };
            
            const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
            const material = new THREE.MeshPhongMaterial({
              color: 0x00a0ff,
              side: THREE.DoubleSide,
              flatShading: true
            });
            
            const mesh = new THREE.Mesh(geometry, material);
            
            // 创建边界线
            const edges = new THREE.EdgesGeometry(geometry);
            const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 1 });
            const line = new THREE.LineSegments(edges, lineMaterial);
            
            map.add(mesh, line);
          } else if (feature.geometry.type === 'MultiPolygon') {
            feature.geometry.coordinates.forEach(polygons => {
              polygons.forEach(polygonCoords => {
                const shape = new THREE.Shape();
                
                polygonCoords.forEach(([lng, lat], i) => {
                  try {
                    const [x, y] = projection([lng, lat]);
                    if (typeof x === 'number' && typeof y === 'number' && !isNaN(x) && !isNaN(y)) {
                      const px = x - window.innerWidth / 2;
                      const py = -y + window.innerHeight / 2;
                      
                      if (i === 0) {
                        shape.moveTo(px, py);
                      }
                      shape.lineTo(px, py);
                    } else {
                      console.warn(`Invalid coordinates at index ${i}: [${lng}, ${lat}]`);
                    }
                  } catch (error) {
                    console.error(`Error processing coordinates at index ${i}:`, error);
                  }
                });
                
                const extrudeSettings = {
                  depth: 10, // 设置地图厚度
                  bevelEnabled: false
                };
                
                const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
                const material = new THREE.MeshPhongMaterial({
                  color: 0x00a0ff,
                  side: THREE.DoubleSide,
                  flatShading: true
                });
                
                const mesh = new THREE.Mesh(geometry, material);
                
                // 创建边界线
                const edges = new THREE.EdgesGeometry(geometry);
                const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 1 });
                const line = new THREE.LineSegments(edges, lineMaterial);
                
                map.add(mesh, line);
              });
            });
          }
        });
        
        scene.add(map);
        
        // 添加环境光和平行光以增强3D效果
        const ambientLight = new THREE.AmbientLight(0x404040);
        scene.add(ambientLight);
        
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(1, 1, 1);
        scene.add(directionalLight);
      })
      .catch(error => {
        console.error('加载 GeoJSON 文件时出错:', error);
      });

    const animate = () => {
      requestAnimationFrame(animate);
      renderer.render(scene, camera);
    };

    animate();

    scene.value = scene;
    projection.value = projection;
    let arryDame = [[116.412318,39.925781],[113.523367,31.03799]];
    // 确保projection已初始化后再调用createLightPillar
    if (projection.value) {
        setTimeout(() => {
        createLightPillar(arryDame);
        }, 5000);
    } else {
      console.error('Projection function is not available');
    }
    
    
  });
</script>

<style scoped>
/* 可以添加样式 */
</style>